package org.fast.framework.helper;

import org.fast.framework.annotation.Autowired;
import org.fast.framework.container.BeanContainer;
import org.fast.framework.container.ClassContainer;
import org.fast.framework.util.ReflectionUtil;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.Set;

/**
 * 依赖注入助手类
 */
public final class IocHelper {

    static {
        // 获取所有Bean类与Bean实例之间的映射关系
        Map<Class<?>, Object> beanMap = BeanContainer.getBeanMap();
        // 遍历BeanMap
        for (Map.Entry<Class<?>, Object> beanEntry : beanMap.entrySet()) {
            // 从BeanMap中获取Bean类与Bean实例
            Class<?> beanClass = beanEntry.getKey();
            Object beanInstance = beanEntry.getValue();
            // 获取Bean类定义的所有成员变量
            Field[] beanFields = beanClass.getDeclaredFields();
            // 遍历Bean Field
            for (Field beanField : beanFields) {
                // 判断当前Bean Field是否带有Autowired注解
                if (beanField.isAnnotationPresent(Autowired.class)) {
                    // 在BeanMap中获取Bean Field对应的实例
                    Class<?> beanFieldClass = beanField.getType();
                    if (beanFieldClass.isInterface()) { // 如果成员变量是接口
                        Object beanFieldInstance;
                        // 获取接口的实现类实例
                        Set<Class<?>> classSet = ClassContainer.getBeanClassSet();
                        for (Class<?> clazz : classSet) {
                            if (beanFieldClass.isAssignableFrom(clazz) && !beanFieldClass.equals(clazz)) {
                                beanFieldInstance = beanMap.get(clazz);
                                if (beanFieldInstance != null) {
                                    // 通过反射初始化BeanField的值
                                    ReflectionUtil.setField(beanInstance, beanField, beanFieldInstance);
                                    break;
                                }
                            }
                        }
                    } else {
                        Object beanFieldInstance = beanMap.get(beanFieldClass);
                        if (beanFieldInstance != null) {
                            // 通过反射初始化BeanField的值
                            ReflectionUtil.setField(beanInstance, beanField, beanFieldInstance);
                        }
                    }
                }
            }
        }
    }
}
